package bipartite;

import java.io.*;
import java.util.*;

import core.SimpleGraph;
import core.Vertex;

public class BipartiteGraph
{
	public static void main(String[] args) throws Exception
	{
		int n, m, maxCapacity, i, j, minCapacity;
		double maxProbability, value, x;
		n = Integer.parseInt(args[0]);
		m = Integer.parseInt(args[1]);
		maxProbability = Double.parseDouble(args[2]);
		if(maxProbability > 1)
		{
			System.out.println("Max probability should be less than or equal to 1");
			return;
		}
		minCapacity = Integer.parseInt(args[3]);
		maxCapacity = Integer.parseInt(args[4]);
		String directory = System.getProperty("user.dir");
		String fileName = args[5] + ".txt";	
		try
		{
			PrintWriter outFile = new  PrintWriter(new FileWriter(new File(directory, fileName)));

			double[][] edge = new double[n][m];
			for(i=0; i<n; i++)
			{
				for(j=0; j<m; j++)
				{
					value = Math.random();
					if(value <= maxProbability)
						edge[i][j] = value;
					else
						edge[i][j] = 0;
				}
			}
						

			//computing the edges out of source
			for (i = 0; i < n; i++)
			{
				x=Math.random();
				//Compute a capacity in range of [minCapacity, maxCapacity]
				value = Math.floor(minCapacity + (x * (maxCapacity - minCapacity + 1)));
				outFile.println("\t" + "s" + "\tl" + (i + 1) + "\t" + (int)value);
			}
			for(i=0; i<n; i++)
			{
				for(j=0; j<m; j++)
				{				
					if(edge[i][j] > 0)
					{
						edge[i][j] = Math.floor(minCapacity + (edge[i][j] * (maxCapacity - minCapacity + 1)));
						//computing for the vertices between source and sink and writing them to the output file
						outFile.println("\tl"+ (i+1) + "\tr" + (j+1) + "\t" + (int)edge[i][j]);
					}
				}
			}
			//computing the edges into the sink
			for (j=0; j < m; j++)
			{
				x=Math.random();
				value = Math.floor(minCapacity + (x * (maxCapacity - minCapacity + 1)));
				outFile.println("\tr" + (j + 1) + "\t" + "t" + "\t" + (int)value);
			}

			//System.out.println("\n\nOutput is created at: \t" + directory + "\\" + fileName);
			outFile.close();
		}
		catch(Exception ex)
		{
			System.out.println(ex);
		}
	}

	//helper functions
	public static String GetString() throws IOException 
	{
		BufferedReader stringIn = new BufferedReader (new
			InputStreamReader(System.in));
		return  stringIn.readLine();
	}

	public static int GetInt() throws IOException 
	{
		String aux = GetString();
		return Integer.parseInt(aux);
	}

	public static double GetReal() throws IOException 
	{
		String  aux = GetString();
		Double d  = new Double(aux);
		return  d.doubleValue() ;
	}
	
	/**
	 * Generates a new pseudo-random Bipartite Graph.
	 * @author Michael Pitts based on above code
	 * @param n number of nodes on the source side.
	 * @param m number of nodes on the sink side.
	 * @param maxCapacity maximum capacity of each edge.
	 * @param minCapacity minimum capacity of each edge.
	 * @param maxProbability maximum probability, must be one or less.
	 * @return a new Bipartite SimpleGraph.
	 */
	public static SimpleGraph getGraph(final int n, final int m, 
			final int maxCapacity, final int minCapacity, 
			final double maxProbability) {
		final SimpleGraph graph = new SimpleGraph();
		int i, j;
		double value, x;
		final Map<Integer, Vertex> left_nodes = new HashMap<Integer, Vertex>(n);
		final Map<Integer, Vertex> right_nodes = new HashMap<Integer, Vertex>(m);
		for (int k = 0; k < n; k++) 
			left_nodes.put(k, graph.insertVertex(null, "l" + k));
		for (int k = 0; k < m; k++)
			right_nodes.put(k, graph.insertVertex(null, "r" + k));
		// generate edges between left and right set
		for(i=0; i<n; i++) {
			for(j=0; j<m; j++) {
				value = Math.random();
				if(value <= maxProbability) {
					value = Math.floor(minCapacity+(value*(maxCapacity-minCapacity+1)));
					graph.insertEdge(left_nodes.get(i), right_nodes.get(j), value, null);
				}
			}
		}			
			//computing the edges out of source
		final Vertex source = graph.insertVertex(null, "s");
		for (i = 0; i < n; i++) {
			x=Math.random();
			//Compute a capacity in range of [minCapacity, maxCapacity]
			value = Math.floor(minCapacity + (x * (maxCapacity - minCapacity + 1)));
			graph.insertEdge(source, left_nodes.get(i), value, null);
		}
		//computing the edges into the sink
		final Vertex sink = graph.insertVertex(null, "t");
		for (j=0; j < m; j++) {
			x=Math.random();
			value = Math.floor(minCapacity + (x * (maxCapacity - minCapacity + 1)));
			graph.insertEdge(right_nodes.get(j), sink, value, null);
		}
		return graph;
	}
}